#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef ESTRUCTURASFS_H_
#define ESTRUCTURASFS_H_
#define FAT_CLUSTER_SIZE 4096
#define fat_ClusterLibre 0x00000000
typedef uint8_t cluster[FAT_CLUSTER_SIZE];

#define LongDir_ULTIMO(Ord)        ((Ord & 0x40) == 0x40)
#define LongDir_NULL(character)   (character == 0x00)
#define Atributo_READ_ONLY 0x1
#define Atributo_HIDDEN 0x2
#define Atributo_SYSTEM 0x4
#define Atributo_VOLUME_ID 0x8
#define Atributo_DIRECTORY 0x10
#define Atributo_ARCHIVE 0x20
#define Atributo_LONG_NAME (Atributo_READ_ONLY | Atributo_HIDDEN | Atributo_SYSTEM | Atributo_VOLUME_ID)

//

/**************ESTRUCTURA BOOT SECTOR*****************/

typedef struct {
        uint8_t Boot_JumpInstruction[3];      //cantidad_byte: 3
        uint8_t Boot_OEMName[8];              //cantidad_byte: 8
        uint16_t Boot_BytesPorSector;         //cantidad_byte: 2
        uint8_t Boot_SectoresPorCluster;      //cantidad_byte: 1
        uint16_t Boot_ReservedSectorCount;    //cantidad_byte: 2
        uint8_t Boot_NumeroDeFATs;            //cantidad_byte: 1
        uint16_t Boot_RootDirectoryFat12;     //cantidad_byte: 2
        uint16_t Boot_TotalSectores13;        //cantidad_byte: 2
        uint8_t Boot_MediaDescriptor;         //cantidad_byte: 1
        uint16_t Boot_SectoresPorFat12;       //cantidad_byte: 2
        uint16_t Boot_SectorsPerTrack;        //cantidad_byte: 2
        uint16_t Boot_NumberOfHeads;          //cantidad_byte: 2
        uint32_t Boot_CantSectoresAntesFat;   //cantidad_byte: 4
        uint32_t Boot_TotalSectoresFat20;     //cantidad_byte: 4
                                              //TOTAL: 36
        //Extended BIOS
        uint32_t Extended_SectoresPorFat32;
        uint16_t Extended_FATFlags;
        uint16_t Extended_Version;
        uint32_t Extended_ClusterRoot;
        uint16_t Extended_SectorFsInfo;
        uint16_t Extended_SectorBootCopy;

}__attribute__ ((packed)) bootSector;


/**************ESTRUCTURA FS INFORMATION SECTOR*****************/

typedef struct {
	        char Fs_SectorSignature[4];
	        uint8_t Fs_Reserved[480];
	        char Fs_SectorSignature2[4];
	        uint32_t Fs_FreeCluster;
	        uint32_t Fs_RecentlyCluster;
	        uint8_t Fs_Reserved2[12];
	        char Fs_SectorSignature3[4];
	}__attribute__ ((packed)) tipofsIs;

/**************ESTRUCTURA DIRECTORIO*************************/

typedef struct {
	        uint8_t Dir_FileName[8];             //CAMPO 1
	        uint8_t Dir_Extension[3];
	        uint8_t Dir_Attribute;               //CAMPO 3
	        uint8_t Dir_Reserved;                //CAMPO 4
	        uint8_t Dir_CreateTime10Ms;          //CAMPO 5
	        uint16_t Dir_CreateTime;             //CAMPO 6
	        uint16_t Dir_CreateDate;             //CAMPO 7
	        uint16_t Dir_LastAccessDate;         //CAMPO 8
	        uint16_t Dir_FirstClusterhigh;       //CAMPO 9
	        uint16_t Dir_LastModifiedTime;       //CAMPO 10
	        uint16_t Dir_LastModifiedDate;       //CAMPO 11
	        uint16_t Dir_FirstClusterLow;        //CAMPO 12
	        uint32_t Dir_FileSize;               //CAMPO 13
} __attribute__ ((packed)) entradaDirectory;

/**************ESTRUCTURA LONG FILE NAMES*************************/

typedef struct {
        uint8_t LongDir_SequenceNumber;
        uint16_t LongDir_Name1[5];
        uint8_t LongDir_Attributes;
        uint8_t LongDir_Reserved;
        uint8_t LongDir_Checksum;
        uint16_t LongDir_Name2[6];
        uint16_t LongDir_FirstCluster;
        uint16_t LongDir_Name3[2];
} __attribute__ ((packed)) LongDir;

/**************ESTRUCTURA FILE*************************/
typedef struct {
        uint32_t ClusterDirEntries;        //CLUSTER DONDE SE ENCUENTRAN LOS DirENTRIES DEL ARCHIVO/DIRECTORIO
        uint32_t SectorClusterDirEntries;  //SECTOR DEL CLUSTER DirEntries
        uint32_t ClusterContenido;         //1er CLUSTER DEL CONTENIDO
        uint32_t nextCluster;              //HIGH + LOW DEL DirEntry
        entradaDirectory firstEntry;       // LDirEntry DEL ARCHIVO/DIRECTORIO
        LongDir lastEntry;                 // DirEntry DEL ARCHIVO/DIRECTORIO
        uint32_t dirEntryOffset;           //TAMAÑO TOTAL DE LOS DirEntries YA LEIDOS (SOLO PARA DIRECTORIOS)
        uint8_t flag;
} __attribute__ ((packed)) File;

/**************ESTRUCTURA INFORMACION*************************/
typedef struct {
uint16_t bytesPorSec;
uint16_t sectPorClust;
uint16_t bytesPorClust;
uint16_t primerSectorDato;
uint16_t cantSectoresReservados;
uint8_t cantidadDeFats;
uint16_t tamFatEnSectors;
uint16_t sectorComienzoFat;
uint32_t cantidadClusters;
uint32_t cantidadSectores;
uint32_t cantidadDataSectores;
uint32_t numeroClusterDelRootDirectory;
int32_t disk;                          /*disk file descriptor - solo ese usa en los tests */
} __attribute__ ((packed)) informacion;

/**************ESTRUCTURA ARCHIVO*************************/
typedef struct {
        int hasLongNameEntry;
        LongDir longNameEntry;
        entradaDirectory dataEntry;
} __attribute__ ((packed)) fileEntry;

/**************ESTRUCTURA ARCHIVO*************************/
struct fat_directory_contents {
        fileEntry fileEntr;
        struct directoryContents * next;
};

/**************ESTRUCTURA ARCHIVO*************************/
typedef struct directoryContents fileList;



#endif /* ESTRUCTURASFS_H_ */
